<template>
  <el-card shadow="hover">
    <el-button
      type="primary"
      :icon="Plus"
      @click="showAddOrUpdateTrademarkDialog()"
    >
      添加品牌
    </el-button>

    <!-- 
      el-table
        border 带边框

      el-table-column 列（有几个组件，table就会渲染几列）
        label 列的标题
        width 列的宽高（不指定就平分）
        align 对齐方式（默认值 left）
        prop 指定要渲染数据中哪个属性的值
        type="index" 渲染序号
     -->
    <el-table
      border
      class="trademark-table"
      :data="trademarkList"
      v-loading="loading"
    >
      <el-table-column
        label="序号"
        width="80"
        align="center"
        type="index"
      ></el-table-column>
      <el-table-column label="品牌名称" prop="tmName"></el-table-column>
      <el-table-column label="品牌LOGO" prop="logoUrl">
        <template v-slot="{ row }">
          <!-- 
            row 渲染的某行数据
           -->
          <el-image :src="row.logoUrl" lazy class="trademark-img" />
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <!-- 
          没有传递默认插槽，就会渲染prop或type="index"对应的值
          传递默认插槽，就会渲染默认插槽
        -->
        <template v-slot="{ row }">
          <el-button
            type="warning"
            :icon="Edit"
            size="small"
            title="修改品牌"
            @click="showAddOrUpdateTrademarkDialog(row)"
          ></el-button>
          <el-button
            type="danger"
            :icon="Delete"
            size="small"
            title="删除品牌"
            @click="delTrademark(row)"
          ></el-button>
        </template>
      </el-table-column>
    </el-table>

    <!-- 
      v-model:current-page 当前页码
      v-model:page-size    每页条数
      page-sizes           每页条数选项
      layout               要加载的分页器结构和顺序
      total                总数
      @size-change         当 page-size 发生变化触发的事件
      @current-change      当 current-page 发生变化触发的事件
     -->
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[3, 6, 9, 12]"
      layout="prev, pager, next, jumper, ->, sizes, total"
      :total="total"
      @size-change="getTrademarkList"
      @current-change="getTrademarkList"
    />

    <el-dialog
      v-model="dialogVisible"
      :title="`${trademarkFormData.id > 0 ? '修改' : '添加'}品牌`"
    >
      <el-form
        label-width="100px"
        ref="trademarkFormRef"
        :model="trademarkFormData"
        :rules="trademarkFormRules"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input
            placeholder="请输入品牌名称"
            v-model="trademarkFormData.tmName"
          ></el-input>
        </el-form-item>
        <el-form-item label="品牌LOGO" prop="logoUrl">
          <!-- 
            action 上传服务器地址
              action="/admin/product/fileUpload" 请求404
              action="http://gmall-h5-api.atguigu.cn/admin/product/fileUpload" 会有跨域
              action="/app-dev/admin/product/fileUpload" 走代理服务器，解决跨域
                问题：开发环境OK，生产环境前缀不一样有问题

                通过 import.meta.env.VITE_API_URL 获取请求前缀，在设置上去
                :action="`${BASE_URL}/admin/product/fileUpload`"
            
            :show-file-list="false" 不要展示文件列表，只能上传一张图片
            :on-success="handleAvatarSuccess" 上传图片成功触发回调函数
            :before-upload="beforeAvatarUpload" 上传图片之前触发回调函数（限制图片大小和类型）
           -->
          <el-upload
            class="avatar-uploader"
            :action="`${BASE_URL}/admin/product/fileUpload`"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
          >
            <!-- 默认插槽 -->
            <img
              v-if="trademarkFormData.logoUrl"
              :src="trademarkFormData.logoUrl"
              class="avatar"
            />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            <!-- 具名插槽 -->
            <template #tip>
              <p>只能上传jpg/png文件，且不超过200kb</p>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>

      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="addOrUpdateTrademark">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>

<script lang="ts" setup>
import { ref, onMounted, reactive } from "vue";
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import {
  getTrademarkListApi,
  addTrademarkApi,
  updateTrademarkApi,
  delTrademarkApi,
} from "@/api/product/trademark";
import type {
  TrademarkList,
  TrademarkItem,
} from "@/api/product/models/trademarkModels";
import type { UploadProps } from "element-plus";

defineOptions({
  name: "Trademark",
});

// 5. 删除品牌
const delTrademark = (row: TrademarkItem) => {
  ElMessageBox.confirm(`您确认要删除 ${row.tmName} 品牌吗?`, "删除", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(async () => {
      // 发送请求，删除品牌
      await delTrademarkApi(row.id);
      ElMessage.success("删除品牌成功");
      getTrademarkList();
    })
    .catch(() => {
      // 为了避免promise失败状态报错
    });
};

// 4. 更新品牌
// const showUpdateTrademarkDialog = (row: TrademarkItem) => {
//   dialogVisible.value = true;
//   trademarkFormData.tmName = row.tmName;
//   trademarkFormData.logoUrl = row.logoUrl;
//   trademarkFormData.id = row.id;
//   trademarkFormRef.value.clearValidate(); // 清空整个表单校验信息
// };

// 2. 添加品牌
const dialogVisible = ref(false);

// const showAddTrademarkDialog = () => {
//   dialogVisible.value = true;
//   trademarkFormData.tmName = "";
//   trademarkFormData.logoUrl = "";
//   trademarkFormData.id = -1;
//   trademarkFormRef.value.clearValidate(); // 清空整个表单校验信息
// };

const showAddOrUpdateTrademarkDialog = (
  row: TrademarkItem = { tmName: "", logoUrl: "", id: -1 }
) => {
  dialogVisible.value = true;
  trademarkFormData.tmName = row.tmName;
  trademarkFormData.logoUrl = row.logoUrl;
  trademarkFormData.id = row.id;
  // Cannot read properties of undefined (reading 'clearValidate')
  // clearValidate前面的内容是undefined
  // trademarkFormRef.value 获取form表单组件实例对象
  trademarkFormRef.value?.clearValidate(); // 清空整个表单校验信息
};

// 表单数据
const trademarkFormData = reactive({
  id: -1, // id > 0 才是有 id
  // 表单项数据定义：看接口文档 -> 添加品牌接口文档
  tmName: "",
  logoUrl: "",
});
// 表单校验规则
const trademarkFormRules = reactive({
  // 表单校验规则要求：规则名称必须和数据名称一致
  tmName: [
    // 组件是el-input, 可以失去焦点
    { required: true, message: "请输入品牌名称", trigger: "blur" },
    { min: 2, max: 10, message: "品牌名称的长度只能为2-10位", trigger: "blur" },
  ],
  logoUrl: [
    // 组件是el-upload组件，没法失去焦点
    {
      required: true,
      message: "请上传品牌LOGO",
      // , trigger: "blur" // 实际默认值是 trigger: "change"
    },
  ],
});

// 在选项式API中：this.$refs.trademarkFormRef 获取组件实例对象
// 在组合式API中：定义一个和ref="trademarkFormRef"名称一致的ref数据, 那么ref数据就能得到组件实例对象
const trademarkFormRef = ref();

const addOrUpdateTrademark = async () => {
  // try {
  // 通过form表单实例对象validate来触发整个表单的表单校验
  await trademarkFormRef.value.validate();

  const id = trademarkFormData.id;

  if (id > 0) {
    await updateTrademarkApi(trademarkFormData);
  } else {
    await addTrademarkApi(trademarkFormData.tmName, trademarkFormData.logoUrl);
  }

  ElMessage.success(`${id > 0 ? "更新" : "添加"}品牌成功`);
  dialogVisible.value = false;
  getTrademarkList();
  // trademarkFormData.tmName = "";
  // trademarkFormData.logoUrl = "";
  // } catch {
  //   console.log("表单校验失败");
  // }
};

// 3. 图片上传功能
const BASE_URL = import.meta.env.VITE_API_URL;

// const imageUrl = ref("");

// 图片会自动上传，上传成功会触发成功回调
const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response
  // uploadFile
) => {
  // response 上传成功服务器的响应返回值
  // uploadFile 上传的这个文件
  // console.log(response, uploadFile);
  // imageUrl.value = URL.createObjectURL(uploadFile.raw!); // 本地图片浏览方案
  // imageUrl.value = response.data; // 服务器返回图片在线访问地址
  trademarkFormData.logoUrl = response.data; // 更新表单数据，将来表单校验才能通过
};

// 图片上传之前触发的回调函数：检查图片大小和类型
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  // rawFile 上传的文件对象
  // rawFile.type 文件类型 image/jpeg image/jpg image/png
  // rawFile.size 文件大小 单位：byte
  const validFileTypes = ["image/jpeg", "image/jpg", "image/png"];

  if (!validFileTypes.includes(rawFile.type)) {
    ElMessage.error("上传的图片只能是jpeg或png格式!");
    return false; // 返回false，就不会上传文件
  } else if (rawFile.size > 200 * 1024) {
    ElMessage.error("上传的图片文件大小不能超过200KB!");
    return false;
  }

  return true; // 返回true，就继续上传文件
};

// 1. 品牌列表分页展示
const trademarkList = ref<TrademarkList>([]);

const currentPage = ref(1); // 当前页码
const pageSize = ref(3); // 每页条数
const total = ref(0); // 总数
const loading = ref(false); // loading

const getTrademarkList = async () => {
  loading.value = true;
  const res = await getTrademarkListApi(currentPage.value, pageSize.value);
  trademarkList.value = res.records;
  total.value = res.total;
  loading.value = false;
};

// 初始化渲染：发送请求获取数据展示
onMounted(getTrademarkList);

// // 当 current-page 发生变化触发的事件
// const handleCurrentChange = () => {
//   getTrademarkList();
// };
// // 当 page-size 发生变化触发的事件
// const handleSizeChange = () => {
//   getTrademarkList();
// };
</script>

<style scoped lang="scss">
.trademark-table {
  margin: 20px 0;
}

.trademark-img {
  width: 150px;
  height: 100px;
}

.avatar-uploader {
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }

  :deep() {
    .el-upload {
      border: 1px dashed var(--el-border-color);
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: var(--el-transition-duration-fast);
    }

    .el-upload:hover {
      border-color: var(--el-color-primary);
    }
  }
}

// .avatar-uploader .avatar {
//   width: 178px;
//   height: 178px;
//   display: block;
// }

// // el-upload是子组件的类名
// .avatar-uploader :deep(.el-upload) {
//   border: 1px dashed var(--el-border-color);
//   border-radius: 6px;
//   cursor: pointer;
//   position: relative;
//   overflow: hidden;
//   transition: var(--el-transition-duration-fast);
// }

// .avatar-uploader :deep(.el-upload:hover) {
//   border-color: var(--el-color-primary);
// }

.el-icon.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}

:deep(.el-form-item__label) {
  font-weight: 700;
}
</style>
